#include "SocketIO.hpp"
#include "header.h"

namespace xww
{

int SocketIO::readn(char * buff, int len)
{
    int left = len;
    char *pbuf = buff;
    while(left > 0)
    {
        int ret = ::recv(_fd, pbuf, left,0);
        if(ret == -1 && errno == EINTR)
        {
            continue; //如果recv被信号中断，继续接收
        }
        else if(ret <= 0)
        {
            return -1; //出错或连接关闭
        }
        else
        {
            left -= ret;
            pbuf += ret;
        }
    }
    return len; //成功读取len字节
}

int SocketIO::sendn(const char *buf,int len)
{
    int left = len;
    const char *pbuf = buf;
    while(left > 0)
    {
        int ret = ::send(_fd, pbuf, left, 0);
        if(ret == -1 && errno == EINTR)
        {
            continue; //如果send被信号中断，继续发送
        }
        else if(ret <= 0)
        {
            return -1; //出错或连接关闭
        }
        else
        {
            left -= ret;
            pbuf += ret;
        }
    }
    return len; //成功发送len字节
}

int SocketIO::readline(char * buff, int maxlen)
{
    int left = maxlen - 1; //留出一个位置给'\0'
    char * pbuf = buff;
    int total = 0; //总共读取的字节数

    while(left > 0)
    {
        int ret = recvPeek(pbuf, left);
        if(ret <= 0) return -1; //出错或连接关闭

        for(int i = 0; i < ret; ++i)
        {
            if(pbuf[i] == '\n') //找到换行符
            {
                int sz = i + 1; //包括换行符的字节数
                ret = readn(pbuf, sz); //读取到缓冲区
                total += ret; //更新总字节数
                pbuf[i] = '\0'; //添加字符串结束符
                return total; //返回读取的总字节数
            }
        }
        ret = readn(pbuf, ret); //没有找到换行符，继续读取
        total += ret;
        left -= ret;
        pbuf += ret;
    }
    buff[maxlen - 1] = '\0'; //如果没有找到换行符，确保字符串以'\0'结尾
    return maxlen - 1;//返回最大长度减1
}

int SocketIO::recvPeek(char * buff, int maxlen) const
{
    int ret = 0;
    do{
        ret = ::recv(_fd, buff, maxlen, MSG_PEEK);
    }while(ret == -1 && errno == EINTR);
    if(ret < 0)
    {
        perror("recvPeek");
    }
    return ret;
}

}// end of namespace xww